﻿using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Sage.JsonConverters
{
    /// <summary>
    /// 提供安全的JSON转换器集合，防止反序列化异常
    /// </summary>
    public static partial class SafeJsonConverters
    {
        /// <summary>
        /// 安全的多类型转整数转换器
        /// 支持：数字、字符串数字、空字符串(返回0)、null(返回0)、空白字符串(返回0)
        /// 绝对不会抛出异常，无效数据返回默认值0，处理数值溢出
        /// </summary>
        public sealed class SafeIntConverter : JsonConverter<int>
        {
            /// <summary>
            /// 从JSON读取器中安全地读取整数值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <param name="typeToConvert">要转换的类型</param>
            /// <param name="options">序列化选项</param>
            /// <returns>安全转换后的整数值，失败时返回0</returns>
            public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                return reader.TokenType switch
                {
                    JsonTokenType.Number => TryGetIntSafely(ref reader),
                    JsonTokenType.String when TryParseIntSafely(reader.GetString(), out var result) => result,
                    JsonTokenType.String or JsonTokenType.Null => 0,
                    _ => 0
                };
            }

            /// <summary>
            /// 将整数值写入JSON写入器
            /// </summary>
            /// <param name="writer">JSON写入器</param>
            /// <param name="value">要写入的整数值</param>
            /// <param name="options">序列化选项</param>
            public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
            {
                writer.WriteNumberValue(value);
            }

            /// <summary>
            /// 安全地从JSON数字获取int，处理所有数值类型和溢出情况
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <returns>安全转换后的整数值</returns>
            private static int TryGetIntSafely(ref Utf8JsonReader reader)
            {
                try
                {
                    if (reader.TryGetInt32(out var intValue))
                        return intValue;

                    if (reader.TryGetInt64(out var longValue))
                    {
                        return longValue switch
                        {
                            > int.MaxValue => int.MaxValue,
                            < int.MinValue => int.MinValue,
                            _ => (int)longValue
                        };
                    }

                    if (reader.TryGetDecimal(out var decimalValue))
                    {
                        return decimalValue switch
                        {
                            > int.MaxValue => int.MaxValue,
                            < int.MinValue => int.MinValue,
                            _ => (int)decimalValue
                        };
                    }

                    if (reader.TryGetDouble(out var doubleValue))
                    {
                        if (double.IsNaN(doubleValue) || double.IsInfinity(doubleValue))
                            return 0;

                        return doubleValue switch
                        {
                            > int.MaxValue => int.MaxValue,
                            < int.MinValue => int.MinValue,
                            _ => (int)doubleValue
                        };
                    }

                    return 0;
                }
                catch
                {
                    return 0;
                }
            }

            /// <summary>
            /// 安全地解析字符串为整数
            /// </summary>
            /// <param name="value">要解析的字符串</param>
            /// <param name="result">解析结果</param>
            /// <returns>是否解析成功</returns>
            private static bool TryParseIntSafely(string? value, out int result)
            {
                result = 0;
                return !string.IsNullOrWhiteSpace(value) && int.TryParse(value.Trim(), out result);
            }
        }

        /// <summary>
        /// 安全的可空整数转换器（推荐用于第三方API）
        /// 支持：数字、字符串数字、空字符串(返回null)、null(返回null)、无效格式(返回null)
        /// 绝对不会抛出异常
        /// </summary>
        public sealed class SafeNullableIntConverter : JsonConverter<int?>
        {
            /// <summary>
            /// 从JSON读取器中安全地读取可空整数值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <param name="typeToConvert">要转换的类型</param>
            /// <param name="options">序列化选项</param>
            /// <returns>安全转换后的可空整数值</returns>
            public override int? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                return reader.TokenType switch
                {
                    JsonTokenType.Null => null,
                    JsonTokenType.Number => TryGetIntSafely(ref reader),
                    JsonTokenType.String when TryParseIntSafely(reader.GetString(), out var result) => result,
                    JsonTokenType.String or _ => null
                };
            }

            /// <summary>
            /// 将可空整数值写入JSON写入器
            /// </summary>
            /// <param name="writer">JSON写入器</param>
            /// <param name="value">要写入的可空整数值</param>
            /// <param name="options">序列化选项</param>
            public override void Write(Utf8JsonWriter writer, int? value, JsonSerializerOptions options)
            {
                if (value.HasValue)
                    writer.WriteNumberValue(value.Value);
                else
                    writer.WriteNullValue();
            }

            /// <summary>
            /// 安全地从JSON数字获取可空整数，处理所有数值类型和溢出情况
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <returns>安全转换后的可空整数值</returns>
            private static int? TryGetIntSafely(ref Utf8JsonReader reader)
            {
                try
                {
                    if (reader.TryGetInt32(out var intValue))
                        return intValue;

                    if (reader.TryGetInt64(out var longValue))
                    {
                        return longValue switch
                        {
                            > int.MaxValue => int.MaxValue,
                            < int.MinValue => int.MinValue,
                            _ => (int)longValue
                        };
                    }

                    if (reader.TryGetDecimal(out var decimalValue))
                    {
                        return decimalValue switch
                        {
                            > int.MaxValue => int.MaxValue,
                            < int.MinValue => int.MinValue,
                            _ => (int)decimalValue
                        };
                    }

                    if (reader.TryGetDouble(out var doubleValue))
                    {
                        if (double.IsNaN(doubleValue) || double.IsInfinity(doubleValue))
                            return null;

                        return doubleValue switch
                        {
                            > int.MaxValue => int.MaxValue,
                            < int.MinValue => int.MinValue,
                            _ => (int)doubleValue
                        };
                    }

                    return null;
                }
                catch
                {
                    return null;
                }
            }

            /// <summary>
            /// 安全地解析字符串为整数
            /// </summary>
            /// <param name="value">要解析的字符串</param>
            /// <param name="result">解析结果</param>
            /// <returns>是否解析成功</returns>
            private static bool TryParseIntSafely(string? value, out int result)
            {
                result = 0;
                return !string.IsNullOrWhiteSpace(value) && int.TryParse(value.Trim(), out result);
            }
        }

        /// <summary>
        /// 安全的长整数转换器
        /// 支持64位整数的安全转换，绝对不会抛出异常
        /// </summary>
        public sealed class SafeLongConverter : JsonConverter<long>
        {
            /// <summary>
            /// 从JSON读取器中安全地读取长整数值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <param name="typeToConvert">要转换的类型</param>
            /// <param name="options">序列化选项</param>
            /// <returns>安全转换后的长整数值，失败时返回0</returns>
            public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                return reader.TokenType switch
                {
                    JsonTokenType.Number => TryGetLongSafely(ref reader),
                    JsonTokenType.String when TryParseLongSafely(reader.GetString(), out var result) => result,
                    JsonTokenType.String or JsonTokenType.Null => 0L,
                    _ => 0L
                };
            }

            /// <summary>
            /// 将长整数值写入JSON写入器
            /// </summary>
            /// <param name="writer">JSON写入器</param>
            /// <param name="value">要写入的长整数值</param>
            /// <param name="options">序列化选项</param>
            public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options)
            {
                writer.WriteNumberValue(value);
            }

            /// <summary>
            /// 安全地从JSON数字获取长整数，处理所有数值类型和溢出情况
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <returns>安全转换后的长整数值</returns>
            private static long TryGetLongSafely(ref Utf8JsonReader reader)
            {
                try
                {
                    if (reader.TryGetInt64(out var longValue))
                        return longValue;

                    if (reader.TryGetInt32(out var intValue))
                        return intValue;

                    if (reader.TryGetDecimal(out var decimalValue))
                    {
                        return decimalValue switch
                        {
                            > long.MaxValue => long.MaxValue,
                            < long.MinValue => long.MinValue,
                            _ => (long)decimalValue
                        };
                    }

                    if (reader.TryGetDouble(out var doubleValue))
                    {
                        if (double.IsNaN(doubleValue) || double.IsInfinity(doubleValue))
                            return 0;

                        return doubleValue switch
                        {
                            > long.MaxValue => long.MaxValue,
                            < long.MinValue => long.MinValue,
                            _ => (long)doubleValue
                        };
                    }

                    return 0;
                }
                catch
                {
                    return 0;
                }
            }

            /// <summary>
            /// 安全地解析字符串为长整数
            /// </summary>
            /// <param name="value">要解析的字符串</param>
            /// <param name="result">解析结果</param>
            /// <returns>是否解析成功</returns>
            private static bool TryParseLongSafely(string? value, out long result)
            {
                result = 0L;
                return !string.IsNullOrWhiteSpace(value) && long.TryParse(value.Trim(), out result);
            }
        }

        /// <summary>
        /// 安全的可空长整数转换器
        /// </summary>
        public sealed class SafeNullableLongConverter : JsonConverter<long?>
        {
            /// <summary>
            /// 从JSON读取器中安全地读取可空长整数值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <param name="typeToConvert">要转换的类型</param>
            /// <param name="options">序列化选项</param>
            /// <returns>安全转换后的可空长整数值</returns>
            public override long? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                return reader.TokenType switch
                {
                    JsonTokenType.Null => null,
                    JsonTokenType.Number => TryGetLongSafely(ref reader),
                    JsonTokenType.String when TryParseLongSafely(reader.GetString(), out var result) => result,
                    JsonTokenType.String or _ => null
                };
            }

            /// <summary>
            /// 将可空长整数值写入JSON写入器
            /// </summary>
            /// <param name="writer">JSON写入器</param>
            /// <param name="value">要写入的可空长整数值</param>
            /// <param name="options">序列化选项</param>
            public override void Write(Utf8JsonWriter writer, long? value, JsonSerializerOptions options)
            {
                if (value.HasValue)
                    writer.WriteNumberValue(value.Value);
                else
                    writer.WriteNullValue();
            }

            /// <summary>
            /// 安全地从JSON数字获取可空长整数，处理所有数值类型和溢出情况
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <returns>安全转换后的可空长整数值</returns>
            private static long? TryGetLongSafely(ref Utf8JsonReader reader)
            {
                try
                {
                    if (reader.TryGetInt64(out var longValue))
                        return longValue;

                    if (reader.TryGetInt32(out var intValue))
                        return intValue;

                    if (reader.TryGetDecimal(out var decimalValue))
                    {
                        return decimalValue switch
                        {
                            > long.MaxValue => long.MaxValue,
                            < long.MinValue => long.MinValue,
                            _ => (long)decimalValue
                        };
                    }

                    if (reader.TryGetDouble(out var doubleValue))
                    {
                        if (double.IsNaN(doubleValue) || double.IsInfinity(doubleValue))
                            return null;

                        return doubleValue switch
                        {
                            > long.MaxValue => long.MaxValue,
                            < long.MinValue => long.MinValue,
                            _ => (long)doubleValue
                        };
                    }

                    return null;
                }
                catch
                {
                    return null;
                }
            }

            /// <summary>
            /// 安全地解析字符串为长整数
            /// </summary>
            /// <param name="value">要解析的字符串</param>
            /// <param name="result">解析结果</param>
            /// <returns>是否解析成功</returns>
            private static bool TryParseLongSafely(string? value, out long result)
            {
                result = 0L;
                return !string.IsNullOrWhiteSpace(value) && long.TryParse(value.Trim(), out result);
            }
        }

        /// <summary>
        /// 安全的双精度浮点数转换器
        /// 使用InvariantCulture确保跨文化兼容性，处理特殊值
        /// </summary>
        public sealed class SafeDoubleConverter : JsonConverter<double>
        {
            /// <summary>
            /// 从JSON读取器中安全地读取双精度浮点数值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <param name="typeToConvert">要转换的类型</param>
            /// <param name="options">序列化选项</param>
            /// <returns>安全转换后的双精度浮点数值，失败时返回0.0</returns>
            public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                return reader.TokenType switch
                {
                    JsonTokenType.Number => TryGetDoubleSafely(ref reader),
                    JsonTokenType.String when TryParseDoubleSafely(reader.GetString(), out var result) => result,
                    JsonTokenType.String or JsonTokenType.Null => 0.0,
                    _ => 0.0
                };
            }

            /// <summary>
            /// 将双精度浮点数值写入JSON写入器
            /// </summary>
            /// <param name="writer">JSON写入器</param>
            /// <param name="value">要写入的双精度浮点数值</param>
            /// <param name="options">序列化选项</param>
            public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
            {
                writer.WriteNumberValue(value);
            }

            /// <summary>
            /// 安全地从JSON数字获取双精度浮点数，处理特殊值和类型转换
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <returns>安全转换后的双精度浮点数值</returns>
            private static double TryGetDoubleSafely(ref Utf8JsonReader reader)
            {
                try
                {
                    if (reader.TryGetDouble(out var doubleValue))
                    {
                        // 处理特殊值
                        if (double.IsNaN(doubleValue) || double.IsInfinity(doubleValue))
                            return 0.0;
                        return doubleValue;
                    }

                    if (reader.TryGetDecimal(out var decimalValue))
                        return (double)decimalValue;

                    if (reader.TryGetInt64(out var longValue))
                        return longValue;

                    if (reader.TryGetInt32(out var intValue))
                        return intValue;

                    return 0.0;
                }
                catch
                {
                    return 0.0;
                }
            }

            /// <summary>
            /// 安全地解析字符串为双精度浮点数，过滤特殊值
            /// </summary>
            /// <param name="value">要解析的字符串</param>
            /// <param name="result">解析结果</param>
            /// <returns>是否解析成功</returns>
            private static bool TryParseDoubleSafely(string? value, out double result)
            {
                result = 0.0;
                if (string.IsNullOrWhiteSpace(value))
                    return false;

                if (double.TryParse(value.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out result))
                {
                    // 过滤特殊值
                    if (double.IsNaN(result) || double.IsInfinity(result))
                    {
                        result = 0.0;
                        return false;
                    }
                    return true;
                }
                return false;
            }
        }

        /// <summary>
        /// 安全的可空双精度浮点数转换器
        /// </summary>
        public sealed class SafeNullableDoubleConverter : JsonConverter<double?>
        {
            /// <summary>
            /// 从JSON读取器中安全地读取可空双精度浮点数值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <param name="typeToConvert">要转换的类型</param>
            /// <param name="options">序列化选项</param>
            /// <returns>安全转换后的可空双精度浮点数值</returns>
            public override double? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                return reader.TokenType switch
                {
                    JsonTokenType.Null => null,
                    JsonTokenType.Number => TryGetDoubleSafely(ref reader),
                    JsonTokenType.String when TryParseDoubleSafely(reader.GetString(), out var result) => result,
                    JsonTokenType.String or _ => null
                };
            }

            /// <summary>
            /// 将可空双精度浮点数值写入JSON写入器
            /// </summary>
            /// <param name="writer">JSON写入器</param>
            /// <param name="value">要写入的可空双精度浮点数值</param>
            /// <param name="options">序列化选项</param>
            public override void Write(Utf8JsonWriter writer, double? value, JsonSerializerOptions options)
            {
                if (value.HasValue)
                    writer.WriteNumberValue(value.Value);
                else
                    writer.WriteNullValue();
            }

            /// <summary>
            /// 安全地从JSON数字获取可空双精度浮点数，处理特殊值和类型转换
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <returns>安全转换后的可空双精度浮点数值</returns>
            private static double? TryGetDoubleSafely(ref Utf8JsonReader reader)
            {
                try
                {
                    if (reader.TryGetDouble(out var doubleValue))
                    {
                        if (double.IsNaN(doubleValue) || double.IsInfinity(doubleValue))
                            return null;
                        return doubleValue;
                    }

                    if (reader.TryGetDecimal(out var decimalValue))
                        return (double)decimalValue;

                    if (reader.TryGetInt64(out var longValue))
                        return longValue;

                    if (reader.TryGetInt32(out var intValue))
                        return intValue;

                    return null;
                }
                catch
                {
                    return null;
                }
            }

            /// <summary>
            /// 安全地解析字符串为双精度浮点数，过滤特殊值
            /// </summary>
            /// <param name="value">要解析的字符串</param>
            /// <param name="result">解析结果</param>
            /// <returns>是否解析成功</returns>
            private static bool TryParseDoubleSafely(string? value, out double result)
            {
                result = 0.0;
                if (string.IsNullOrWhiteSpace(value))
                    return false;

                if (double.TryParse(value.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out result))
                {
                    if (double.IsNaN(result) || double.IsInfinity(result))
                        return false;
                    return true;
                }
                return false;
            }
        }

        /// <summary>
        /// 安全的decimal转换器（推荐用于货币和精确计算）
        /// Decimal类型提供更高的精度，适合财务计算
        /// </summary>
        public sealed class SafeDecimalConverter : JsonConverter<decimal>
        {
            /// <summary>
            /// 从JSON读取器中安全地读取decimal值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <param name="typeToConvert">要转换的类型</param>
            /// <param name="options">序列化选项</param>
            /// <returns>安全转换后的decimal值，失败时返回0m</returns>
            public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                return reader.TokenType switch
                {
                    JsonTokenType.Number => TryGetDecimalSafely(ref reader),
                    JsonTokenType.String when TryParseDecimalSafely(reader.GetString(), out var result) => result,
                    JsonTokenType.String or JsonTokenType.Null => 0m,
                    _ => 0m
                };
            }

            /// <summary>
            /// 将decimal值写入JSON写入器
            /// </summary>
            /// <param name="writer">JSON写入器</param>
            /// <param name="value">要写入的decimal值</param>
            /// <param name="options">序列化选项</param>
            public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options)
            {
                writer.WriteNumberValue(value);
            }

            /// <summary>
            /// 安全地从JSON数字获取decimal，处理溢出和特殊值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <returns>安全转换后的decimal值</returns>
            private static decimal TryGetDecimalSafely(ref Utf8JsonReader reader)
            {
                try
                {
                    if (reader.TryGetDecimal(out var decimalValue))
                        return decimalValue;

                    if (reader.TryGetInt64(out var longValue))
                        return longValue;

                    if (reader.TryGetInt32(out var intValue))
                        return intValue;

                    if (reader.TryGetDouble(out var doubleValue))
                    {
                        if (double.IsNaN(doubleValue) || double.IsInfinity(doubleValue))
                            return 0m;

                        try
                        {
                            return (decimal)doubleValue;
                        }
                        catch (OverflowException)
                        {
                            return doubleValue > 0 ? decimal.MaxValue : decimal.MinValue;
                        }
                    }

                    return 0m;
                }
                catch
                {
                    return 0m;
                }
            }

            /// <summary>
            /// 安全地解析字符串为decimal
            /// </summary>
            /// <param name="value">要解析的字符串</param>
            /// <param name="result">解析结果</param>
            /// <returns>是否解析成功</returns>
            private static bool TryParseDecimalSafely(string? value, out decimal result)
            {
                result = 0m;
                return !string.IsNullOrWhiteSpace(value) &&
                       decimal.TryParse(value.Trim(), NumberStyles.Number, CultureInfo.InvariantCulture, out result);
            }
        }

        /// <summary>
        /// 安全的可空decimal转换器
        /// </summary>
        public sealed class SafeNullableDecimalConverter : JsonConverter<decimal?>
        {
            /// <summary>
            /// 从JSON读取器中安全地读取可空decimal值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <param name="typeToConvert">要转换的类型</param>
            /// <param name="options">序列化选项</param>
            /// <returns>安全转换后的可空decimal值</returns>
            public override decimal? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            {
                return reader.TokenType switch
                {
                    JsonTokenType.Null => null,
                    JsonTokenType.Number => TryGetDecimalSafely(ref reader),
                    JsonTokenType.String when TryParseDecimalSafely(reader.GetString(), out var result) => result,
                    JsonTokenType.String or _ => null
                };
            }

            /// <summary>
            /// 将可空decimal值写入JSON写入器
            /// </summary>
            /// <param name="writer">JSON写入器</param>
            /// <param name="value">要写入的可空decimal值</param>
            /// <param name="options">序列化选项</param>
            public override void Write(Utf8JsonWriter writer, decimal? value, JsonSerializerOptions options)
            {
                if (value.HasValue)
                    writer.WriteNumberValue(value.Value);
                else
                    writer.WriteNullValue();
            }

            /// <summary>
            /// 安全地从JSON数字获取可空decimal，处理溢出和特殊值
            /// </summary>
            /// <param name="reader">JSON读取器</param>
            /// <returns>安全转换后的可空decimal值</returns>
            private static decimal? TryGetDecimalSafely(ref Utf8JsonReader reader)
            {
                try
                {
                    if (reader.TryGetDecimal(out var decimalValue))
                        return decimalValue;

                    if (reader.TryGetInt64(out var longValue))
                        return longValue;

                    if (reader.TryGetInt32(out var intValue))
                        return intValue;

                    if (reader.TryGetDouble(out var doubleValue))
                    {
                        if (double.IsNaN(doubleValue) || double.IsInfinity(doubleValue))
                            return null;

                        try
                        {
                            return (decimal)doubleValue;
                        }
                        catch (OverflowException)
                        {
                            return doubleValue > 0 ? decimal.MaxValue : decimal.MinValue;
                        }
                    }

                    return null;
                }
                catch
                {
                    return null;
                }
            }

            /// <summary>
            /// 安全地解析字符串为decimal
            /// </summary>
            /// <param name="value">要解析的字符串</param>
            /// <param name="result">解析结果</param>
            /// <returns>是否解析成功</returns>
            private static bool TryParseDecimalSafely(string? value, out decimal result)
            {
                result = 0m;
                return !string.IsNullOrWhiteSpace(value) &&
                       decimal.TryParse(value.Trim(), NumberStyles.Number, CultureInfo.InvariantCulture, out result);
            }
        }
    }
}